package StructurePattern.Flyweight;

/**
 * @author: Themberfue
 * @date: 2025/8/12 11:21
 * @description:
 */
import java.util.HashMap;
import java.util.Map;

// 1. 抽象享元：字符接口
interface Character {
    // 渲染字符，fontSize和color是外部状态
    void render(int fontSize, String color);
    char getSymbol();
}

// 2. 具体享元：具体字符实现
class ConcreteCharacter implements Character {
    // 内部状态：字符本身（可共享）
    private char symbol;

    public ConcreteCharacter(char symbol) {
        this.symbol = symbol;
        // 模拟创建字符的开销
        System.out.println("创建字符对象: " + symbol);
    }

    @Override
    public char getSymbol() {
        return symbol;
    }

    // 渲染方法，使用外部状态（字体大小和颜色）
    @Override
    public void render(int fontSize, String color) {
        System.out.println("渲染字符: '" + symbol + "' [大小: " + fontSize + ", 颜色: " + color + "]");
    }
}

// 3. 享元工厂：字符工厂
class CharacterFactory {
    // 缓存已创建的享元对象
    private Map<java.lang.Character, Character> characters = new HashMap<>();

    // 获取字符对象，如果已存在则返回缓存的对象，否则创建新对象
    public Character getCharacter(char symbol) {
        // 检查缓存中是否存在
        Character character = characters.get(symbol);

        // 如果不存在则创建并缓存
        if (character == null) {
            character = new ConcreteCharacter(symbol);
            characters.put(symbol, character);
        }

        return character;
    }

    // 获取缓存的享元对象数量
    public int getCharacterCount() {
        return characters.size();
    }
}

// 4. 客户端：文字编辑器
public class FlyweightExample {
    public static void main(String[] args) {
        // 创建字符工厂
        CharacterFactory factory = new CharacterFactory();

        // 要显示的文本（包含重复字符）
        String text = "Hello World! Hello Java!";

        System.out.println("要显示的文本: " + text + "\n");

        // 渲染文本中的每个字符
        for (char c : text.toCharArray()) {
            // 从工厂获取字符（重复字符会使用缓存）
            Character character = factory.getCharacter(c);
            // 随机生成字体大小和颜色（外部状态）
            int fontSize = 12 + (c % 3) * 2; // 简单模拟不同大小
            String color = (c % 2 == 0) ? "黑色" : "蓝色"; // 简单模拟不同颜色
            // 渲染字符
            character.render(fontSize, color);
        }

        // 显示实际创建的字符对象数量（远少于总字符数）
        System.out.println("\n实际创建的字符对象数量: " + factory.getCharacterCount());
        System.out.println("总字符数: " + text.length());
    }
}

